/**
 * ...
 * @author Krzysztof Rozalski
 */

package hapi.remoting;
import hapi.log.LogLevel;
import haxe.remoting.AsyncConnection;

class AsyncConnectionMock implements AsyncConnection {

	var subServices:Hash<AsyncConnectionMock>;
	var service:Dynamic;
	var onError:Dynamic->Void;
	var serviceName:String;
	var delayInMillis:Int;
	
	public function new(?delayInMillis=0) {
		this.subServices = new Hash();
		this.service = null;
		this.serviceName = "";
		this.delayInMillis = delayInMillis;
	}
	
	public function addSubService(name:String, subService:Dynamic, ?delayInMillis=0) {
		var subAsyncService = new AsyncConnectionMock(delayInMillis);
		subAsyncService.service = subService;
		subAsyncService.onError = onError;
		subAsyncService.serviceName = name;
		subServices.set(name, subAsyncService);
	}
	
	public function resolve( name : String ) : AsyncConnection {
		if ( subServices.exists(name)) {
			var subService = subServices.get(name);
			return subService;
		}else if (service != null) {
			var method:Dynamic = null;
			try {
				method = Reflect.field(service, name);
			}catch(e:Dynamic){}
			if ( method != null) {
				var methodMock = new AsyncConnectionMethodMock(name, method, service, delayInMillis);
				methodMock.setErrorHandler(onError);
				return methodMock;
			}
		}
		callOnError("Could not resolve method " + name);
		return null;
	}
	
	public function call( params : Array<Dynamic>, ?callOnResult : Dynamic -> Void ) : Void {
		callOnError("Invalid method call");
	}
	
	public function setErrorHandler( error : Dynamic -> Void ) : Void {
		this.onError = error;
	}
	
	private function callOnError(cause:Dynamic) {
		var message = serviceName == "" ? "" : serviceName + "<"+Type.getClassName(Type.getClass(service))+">: ";
		onError({message:message, cause:cause});
	}
}